/*
* Copyright (C) 1997-2001 Id Software, Inc.
* 
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
* 
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE.
* 
* See the GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*  
*/

// Created on 18.11.2003 by RST.
// $Id: GameFunc.java,v 1.9 2006/01/21 21:53:32 salomo Exp $
using System;
using Defines = Suake2.UI.Defines;
using Globals = Suake2.UI.Globals;
using Lib = Suake2.UI.util.Lib;
using Math3D = Suake2.UI.util.Math3D;
namespace Suake2.UI.game
{
	
	public class GameFunc
	{
		public class AnonymousClassEntThinkAdapter:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "move_done";
				}
				
			}
			public override bool think(edict_t ent)
			{
				Math3D.VectorClear(ent.velocity);
				ent.moveinfo.endfunc.think(ent);
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter1:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "move_final";
				}
				
			}
			public override bool think(edict_t ent)
			{
				
				if (ent.moveinfo.remaining_distance == 0)
				{
					jake2.game.GameFunc.Move_Done.think(ent);
					return true;
				}
				
				Math3D.VectorScale(ent.moveinfo.dir, ent.moveinfo.remaining_distance / Defines.FRAMETIME, ent.velocity);
				
				ent.think = Suake2.UI.game.GameFunc.Move_Done;
				ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter2:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "move_begin";
				}
				
			}
			public override bool think(edict_t ent)
			{
				
				float frames;
				
				if ((ent.moveinfo.speed * Defines.FRAMETIME) >= ent.moveinfo.remaining_distance)
				{
					jake2.game.GameFunc.Move_Final.think(ent);
					return true;
				}
				Math3D.VectorScale(ent.moveinfo.dir, ent.moveinfo.speed, ent.velocity);
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				frames = (float) System.Math.Floor((ent.moveinfo.remaining_distance / ent.moveinfo.speed) / Defines.FRAMETIME);
				ent.moveinfo.remaining_distance -= frames * ent.moveinfo.speed * Defines.FRAMETIME;
				ent.nextthink = GameBase.level.time + (frames * Defines.FRAMETIME);
				ent.think = Suake2.UI.game.GameFunc.Move_Final;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter3:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "agnle_move_done";
				}
				
			}
			public override bool think(edict_t ent)
			{
				Math3D.VectorClear(ent.avelocity);
				ent.moveinfo.endfunc.think(ent);
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter4:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "angle_move_final";
				}
				
			}
			public override bool think(edict_t ent)
			{
				float[] move = new float[]{0, 0, 0};
				
				if (ent.moveinfo.state == jake2.game.GameFunc.STATE_UP)
					Math3D.VectorSubtract(ent.moveinfo.end_angles, ent.s.angles, move);
				else
					Math3D.VectorSubtract(ent.moveinfo.start_angles, ent.s.angles, move);
				
				if (Math3D.VectorEquals(move, Globals.vec3_origin))
				{
					jake2.game.GameFunc.AngleMove_Done.think(ent);
					return true;
				}
				
				Math3D.VectorScale(move, 1.0f / Defines.FRAMETIME, ent.avelocity);
				
				ent.think = Suake2.UI.game.GameFunc.AngleMove_Done;
				ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter5:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "angle_move_begin";
				}
				
			}
			public override bool think(edict_t ent)
			{
				float[] destdelta = new float[]{0, 0, 0};
				float len;
				float traveltime;
				float frames;
				
				// set destdelta to the vector needed to move
				if (ent.moveinfo.state == jake2.game.GameFunc.STATE_UP)
					Math3D.VectorSubtract(ent.moveinfo.end_angles, ent.s.angles, destdelta);
				else
					Math3D.VectorSubtract(ent.moveinfo.start_angles, ent.s.angles, destdelta);
				
				// calculate length of vector
				len = Math3D.VectorLength(destdelta);
				
				// divide by speed to get time to reach dest
				traveltime = len / ent.moveinfo.speed;
				
				if (traveltime < Defines.FRAMETIME)
				{
					jake2.game.GameFunc.AngleMove_Final.think(ent);
					return true;
				}
				
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				frames = (float) (System.Math.Floor(traveltime / Defines.FRAMETIME));
				
				// scale the destdelta vector by the time spent traveling to get
				// velocity
				Math3D.VectorScale(destdelta, 1.0f / traveltime, ent.avelocity);
				
				// set nextthink to trigger a think when dest is reached
				ent.nextthink = GameBase.level.time + frames * Defines.FRAMETIME;
				ent.think = Suake2.UI.game.GameFunc.AngleMove_Final;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter6:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "thinc_accelmove";
				}
				
			}
			public override bool think(edict_t ent)
			{
				ent.moveinfo.remaining_distance -= ent.moveinfo.current_speed;
				
				if (ent.moveinfo.current_speed == 0)
				// starting or blocked
					jake2.game.GameFunc.plat_CalcAcceleratedMove(ent.moveinfo);
				
				jake2.game.GameFunc.plat_Accelerate(ent.moveinfo);
				
				// will the entire move complete on next frame?
				if (ent.moveinfo.remaining_distance <= ent.moveinfo.current_speed)
				{
					jake2.game.GameFunc.Move_Final.think(ent);
					return true;
				}
				
				Math3D.VectorScale(ent.moveinfo.dir, ent.moveinfo.current_speed * 10, ent.velocity);
				ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
				ent.think = Suake2.UI.game.GameFunc.Think_AccelMove;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter7:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "plat_hit_top";
				}
				
			}
			public override bool think(edict_t ent)
			{
				if (0 == (ent.flags & Defines.FL_TEAMSLAVE))
				{
					if (ent.moveinfo.sound_end != 0)
						GameBase.gi.sound(ent, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, ent.moveinfo.sound_end, 1, Defines.ATTN_STATIC, 0);
					ent.s.sound = 0;
				}
				ent.moveinfo.state = Suake2.UI.game.GameFunc.STATE_TOP;
				
				ent.think = Suake2.UI.game.GameFunc.plat_go_down;
				ent.nextthink = GameBase.level.time + 3;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter8:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "plat_hit_bottom";
				}
				
			}
			public override bool think(edict_t ent)
			{
				
				if (0 == (ent.flags & Defines.FL_TEAMSLAVE))
				{
					if (ent.moveinfo.sound_end != 0)
						GameBase.gi.sound(ent, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, ent.moveinfo.sound_end, 1, Defines.ATTN_STATIC, 0);
					ent.s.sound = 0;
				}
				ent.moveinfo.state = Suake2.UI.game.GameFunc.STATE_BOTTOM;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter9:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "plat_go_down";
				}
				
			}
			public override bool think(edict_t ent)
			{
				if (0 == (ent.flags & Defines.FL_TEAMSLAVE))
				{
					if (ent.moveinfo.sound_start != 0)
						GameBase.gi.sound(ent, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, ent.moveinfo.sound_start, 1, Defines.ATTN_STATIC, 0);
					ent.s.sound = ent.moveinfo.sound_middle;
				}
				ent.moveinfo.state = Suake2.UI.game.GameFunc.STATE_DOWN;
				jake2.game.GameFunc.Move_Calc(ent, ent.moveinfo.end_origin, jake2.game.GameFunc.plat_hit_bottom);
				return true;
			}
		}
		public class AnonymousClassEntBlockedAdapter:EntBlockedAdapter
		{
			override public System.String ID
			{
				get
				{
					return "plat_blocked";
				}
				
			}
			public override void  blocked(edict_t self, edict_t other)
			{
				if (0 == (other.svflags & Defines.SVF_MONSTER) && (null == other.client))
				{
					// give it a chance to go away on it's own terms (like gibs)
					GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, 100000, 1, 0, Defines.MOD_CRUSH);
					// if it's still there, nuke it
					if (other != null)
						GameMisc.BecomeExplosion1(other);
					return ;
				}
				
				GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, 1, 0, Defines.MOD_CRUSH);
				
				if (self.moveinfo.state == jake2.game.GameFunc.STATE_UP)
					jake2.game.GameFunc.plat_go_down.think(self);
				else if (self.moveinfo.state == jake2.game.GameFunc.STATE_DOWN)
					jake2.game.GameFunc.plat_go_up(self);
			}
		}
		public class AnonymousClassEntUseAdapter:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_plat";
				}
				
			}
			public override void  use(edict_t ent, edict_t other, edict_t activator)
			{
				if (ent.think != null)
					return ; // already down
				jake2.game.GameFunc.plat_go_down.think(ent);
			}
		}
		public class AnonymousClassEntTouchAdapter:EntTouchAdapter
		{
			override public System.String ID
			{
				get
				{
					return "touch_plat_center";
				}
				
			}
			public override void  touch(edict_t ent, edict_t other, cplane_t plane, csurface_t surf)
			{
				if (other.client == null)
					return ;
				
				if (other.health <= 0)
					return ;
				
				ent = ent.enemy; // now point at the plat, not the trigger
				if (ent.moveinfo.state == jake2.game.GameFunc.STATE_BOTTOM)
					jake2.game.GameFunc.plat_go_up(ent);
				else if (ent.moveinfo.state == jake2.game.GameFunc.STATE_TOP)
				{
					ent.nextthink = GameBase.level.time + 1; // the player is still
					// on the plat, so
					// delay going down
				}
			}
		}
		public class AnonymousClassEntBlockedAdapter1:EntBlockedAdapter
		{
			override public System.String ID
			{
				get
				{
					return "rotating_blocked";
				}
				
			}
			public override void  blocked(edict_t self, edict_t other)
			{
				GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, 1, 0, Defines.MOD_CRUSH);
			}
		}
		public class AnonymousClassEntTouchAdapter1:EntTouchAdapter
		{
			override public System.String ID
			{
				get
				{
					return "rotating_touch";
				}
				
			}
			public override void  touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf)
			{
				if (self.avelocity[0] != 0 || self.avelocity[1] != 0 || self.avelocity[2] != 0)
					GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, 1, 0, Defines.MOD_CRUSH);
			}
		}
		public class AnonymousClassEntUseAdapter1:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "rotating_use";
				}
				
			}
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				if (!Math3D.VectorEquals(self.avelocity, Globals.vec3_origin))
				{
					self.s.sound = 0;
					Math3D.VectorClear(self.avelocity);
					self.touch = null;
				}
				else
				{
					self.s.sound = self.moveinfo.sound_middle;
					Math3D.VectorScale(self.movedir, self.speed, self.avelocity);
					if ((self.spawnflags & 16) != 0)
						self.touch = Suake2.UI.game.GameFunc.rotating_touch;
				}
			}
		}
		public class AnonymousClassEntThinkAdapter10:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "sp_func_rotating";
				}
				
			}
			public override bool think(edict_t ent)
			{
				ent.solid = Defines.SOLID_BSP;
				if ((ent.spawnflags & 32) != 0)
					ent.movetype = Defines.MOVETYPE_STOP;
				else
					ent.movetype = Defines.MOVETYPE_PUSH;
				
				// set the axis of rotation
				Math3D.VectorClear(ent.movedir);
				if ((ent.spawnflags & 4) != 0)
					ent.movedir[2] = 1.0f;
				else if ((ent.spawnflags & 8) != 0)
					ent.movedir[0] = 1.0f;
				// Z_AXIS
				else
					ent.movedir[1] = 1.0f;
				
				// check for reverse rotation
				if ((ent.spawnflags & 2) != 0)
					Math3D.VectorNegate(ent.movedir, ent.movedir);
				
				if (0 == ent.speed)
					ent.speed = 100;
				if (0 == ent.dmg)
					ent.dmg = 2;
				
				//		ent.moveinfo.sound_middle = "doors/hydro1.wav";
				
				ent.use = Suake2.UI.game.GameFunc.rotating_use;
				if (ent.dmg != 0)
					ent.blocked = Suake2.UI.game.GameFunc.rotating_blocked;
				
				if ((ent.spawnflags & 1) != 0)
					ent.use.use(ent, null, null);
				
				if ((ent.spawnflags & 64) != 0)
					ent.s.effects |= Defines.EF_ANIM_ALL;
				if ((ent.spawnflags & 128) != 0)
					ent.s.effects |= Defines.EF_ANIM_ALLFAST;
				
				GameBase.gi.setmodel(ent, ent.model);
				GameBase.gi.linkentity(ent);
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter11:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "button_done";
				}
				
			}
			public override bool think(edict_t self)
			{
				
				self.moveinfo.state = Suake2.UI.game.GameFunc.STATE_BOTTOM;
				self.s.effects &= ~ Defines.EF_ANIM23;
				self.s.effects |= Defines.EF_ANIM01;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter12:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "button_return";
				}
				
			}
			public override bool think(edict_t self)
			{
				self.moveinfo.state = Suake2.UI.game.GameFunc.STATE_DOWN;
				
				jake2.game.GameFunc.Move_Calc(self, self.moveinfo.start_origin, jake2.game.GameFunc.button_done);
				
				self.s.frame = 0;
				
				if (self.health != 0)
					self.takedamage = Defines.DAMAGE_YES;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter13:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "button_wait";
				}
				
			}
			public override bool think(edict_t self)
			{
				self.moveinfo.state = Suake2.UI.game.GameFunc.STATE_TOP;
				self.s.effects &= ~ Defines.EF_ANIM01;
				self.s.effects |= Defines.EF_ANIM23;
				
				GameUtil.G_UseTargets(self, self.activator);
				self.s.frame = 1;
				if (self.moveinfo.wait >= 0)
				{
					self.nextthink = GameBase.level.time + self.moveinfo.wait;
					self.think = Suake2.UI.game.GameFunc.button_return;
				}
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter14:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "button_fire";
				}
				
			}
			public override bool think(edict_t self)
			{
				if (self.moveinfo.state == jake2.game.GameFunc.STATE_UP || self.moveinfo.state == jake2.game.GameFunc.STATE_TOP)
					return true;
				
				self.moveinfo.state = Suake2.UI.game.GameFunc.STATE_UP;
				if (self.moveinfo.sound_start != 0 && 0 == (self.flags & Defines.FL_TEAMSLAVE))
					GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_start, 1, Defines.ATTN_STATIC, 0);
				jake2.game.GameFunc.Move_Calc(self, self.moveinfo.end_origin, jake2.game.GameFunc.button_wait);
				return true;
			}
		}
		public class AnonymousClassEntUseAdapter2:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "button_use";
				}
				
			}
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				self.activator = activator;
				jake2.game.GameFunc.button_fire.think(self);
				return ;
			}
		}
		public class AnonymousClassEntTouchAdapter2:EntTouchAdapter
		{
			override public System.String ID
			{
				get
				{
					return "button_touch";
				}
				
			}
			public override void  touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf)
			{
				if (null == other.client)
					return ;
				
				if (other.health <= 0)
					return ;
				
				self.activator = other;
				jake2.game.GameFunc.button_fire.think(self);
			}
		}
		public class AnonymousClassEntDieAdapter:EntDieAdapter
		{
			override public System.String ID
			{
				get
				{
					return "button_killed";
				}
				
			}
			public override void  die(edict_t self, edict_t inflictor, edict_t attacker, int damage, float[] point)
			{
				self.activator = attacker;
				self.health = self.max_health;
				self.takedamage = Defines.DAMAGE_NO;
				jake2.game.GameFunc.button_fire.think(self);
			}
		}
		public class AnonymousClassEntThinkAdapter15:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "sp_func_button";
				}
				
			}
			public override bool think(edict_t ent)
			{
				float[] abs_movedir = new float[]{0, 0, 0};
				float dist;
				
				GameBase.G_SetMovedir(ent.s.angles, ent.movedir);
				ent.movetype = Defines.MOVETYPE_STOP;
				ent.solid = Defines.SOLID_BSP;
				GameBase.gi.setmodel(ent, ent.model);
				
				if (ent.sounds != 1)
					ent.moveinfo.sound_start = GameBase.gi.soundindex("switches/butn2.wav");
				
				if (0 == ent.speed)
					ent.speed = 40;
				if (0 == ent.accel)
					ent.accel = ent.speed;
				if (0 == ent.decel)
					ent.decel = ent.speed;
				
				if (0 == ent.wait)
					ent.wait = 3;
				if (0 == GameBase.st.lip)
					GameBase.st.lip = 4;
				
				Math3D.VectorCopy(ent.s.origin, ent.pos1);
				abs_movedir[0] = (float) System.Math.Abs(ent.movedir[0]);
				abs_movedir[1] = (float) System.Math.Abs(ent.movedir[1]);
				abs_movedir[2] = (float) System.Math.Abs(ent.movedir[2]);
				dist = abs_movedir[0] * ent.size[0] + abs_movedir[1] * ent.size[1] + abs_movedir[2] * ent.size[2] - GameBase.st.lip;
				Math3D.VectorMA(ent.pos1, dist, ent.movedir, ent.pos2);
				
				ent.use = Suake2.UI.game.GameFunc.button_use;
				ent.s.effects |= Defines.EF_ANIM01;
				
				if (ent.health != 0)
				{
					ent.max_health = ent.health;
					ent.die = Suake2.UI.game.GameFunc.button_killed;
					ent.takedamage = Defines.DAMAGE_YES;
				}
				else if (null == ent.targetname)
					ent.touch = Suake2.UI.game.GameFunc.button_touch;
				
				ent.moveinfo.state = Suake2.UI.game.GameFunc.STATE_BOTTOM;
				
				ent.moveinfo.speed = ent.speed;
				ent.moveinfo.accel = ent.accel;
				ent.moveinfo.decel = ent.decel;
				ent.moveinfo.wait = ent.wait;
				Math3D.VectorCopy(ent.pos1, ent.moveinfo.start_origin);
				Math3D.VectorCopy(ent.s.angles, ent.moveinfo.start_angles);
				Math3D.VectorCopy(ent.pos2, ent.moveinfo.end_origin);
				Math3D.VectorCopy(ent.s.angles, ent.moveinfo.end_angles);
				
				GameBase.gi.linkentity(ent);
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter16:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_hit_top";
				}
				
			}
			public override bool think(edict_t self)
			{
				if (0 == (self.flags & Defines.FL_TEAMSLAVE))
				{
					if (self.moveinfo.sound_end != 0)
						GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_end, 1, Defines.ATTN_STATIC, 0);
					self.s.sound = 0;
				}
				self.moveinfo.state = Suake2.UI.game.GameFunc.STATE_TOP;
				if ((self.spawnflags & jake2.game.GameFunc.DOOR_TOGGLE) != 0)
					return true;
				if (self.moveinfo.wait >= 0)
				{
					self.think = Suake2.UI.game.GameFunc.door_go_down;
					self.nextthink = GameBase.level.time + self.moveinfo.wait;
				}
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter17:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_hit_bottom";
				}
				
			}
			public override bool think(edict_t self)
			{
				if (0 == (self.flags & Defines.FL_TEAMSLAVE))
				{
					if (self.moveinfo.sound_end != 0)
						GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_end, 1, Defines.ATTN_STATIC, 0);
					self.s.sound = 0;
				}
				self.moveinfo.state = Suake2.UI.game.GameFunc.STATE_BOTTOM;
				jake2.game.GameFunc.door_use_areaportals(self, false);
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter18:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_go_down";
				}
				
			}
			public override bool think(edict_t self)
			{
				if (0 == (self.flags & Defines.FL_TEAMSLAVE))
				{
					if (self.moveinfo.sound_start != 0)
						GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_start, 1, Defines.ATTN_STATIC, 0);
					self.s.sound = self.moveinfo.sound_middle;
				}
				if (self.max_health != 0)
				{
					self.takedamage = Defines.DAMAGE_YES;
					self.health = self.max_health;
				}
				
				self.moveinfo.state = Suake2.UI.game.GameFunc.STATE_DOWN;
				if (Lib.strcmp(self.classname, "func_door") == 0)
					jake2.game.GameFunc.Move_Calc(self, self.moveinfo.start_origin, jake2.game.GameFunc.door_hit_bottom);
				else if (Lib.strcmp(self.classname, "func_door_rotating") == 0)
					jake2.game.GameFunc.AngleMove_Calc(self, jake2.game.GameFunc.door_hit_bottom);
				return true;
			}
		}
		public class AnonymousClassEntUseAdapter3:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_use";
				}
				
			}
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				edict_t ent;
				
				if ((self.flags & Defines.FL_TEAMSLAVE) != 0)
					return ;
				
				if ((self.spawnflags & jake2.game.GameFunc.DOOR_TOGGLE) != 0)
				{
					if (self.moveinfo.state == jake2.game.GameFunc.STATE_UP || self.moveinfo.state == jake2.game.GameFunc.STATE_TOP)
					{
						// trigger all paired doors
						for (ent = self; ent != null; ent = ent.teamchain)
						{
							ent.message = null;
							ent.touch = null;
							jake2.game.GameFunc.door_go_down.think(ent);
						}
						return ;
					}
				}
				
				// trigger all paired doors
				for (ent = self; ent != null; ent = ent.teamchain)
				{
					ent.message = null;
					ent.touch = null;
					jake2.game.GameFunc.door_go_up(ent, activator);
				}
			}
		}
		public class AnonymousClassEntTouchAdapter3:EntTouchAdapter
		{
			override public System.String ID
			{
				get
				{
					return "touch_door_trigger";
				}
				
			}
			public override void  touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf)
			{
				if (other.health <= 0)
					return ;
				
				if (0 == (other.svflags & Defines.SVF_MONSTER) && (null == other.client))
					return ;
				
				if (0 != (self.owner.spawnflags & jake2.game.GameFunc.DOOR_NOMONSTER) && 0 != (other.svflags & Defines.SVF_MONSTER))
					return ;
				
				if (GameBase.level.time < self.touch_debounce_time)
					return ;
				self.touch_debounce_time = GameBase.level.time + 1.0f;
				
				jake2.game.GameFunc.door_use.use(self.owner, other, other);
			}
		}
		public class AnonymousClassEntThinkAdapter19:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "think_calc_movespeed";
				}
				
			}
			public override bool think(edict_t self)
			{
				edict_t ent;
				float min;
				float time;
				float newspeed;
				float ratio;
				float dist;
				
				if ((self.flags & Defines.FL_TEAMSLAVE) != 0)
					return true; // only the team master does this
				
				// find the smallest distance any member of the team will be moving
				min = System.Math.Abs(self.moveinfo.distance);
				for (ent = self.teamchain; ent != null; ent = ent.teamchain)
				{
					dist = System.Math.Abs(ent.moveinfo.distance);
					if (dist < min)
						min = dist;
				}
				
				time = min / self.moveinfo.speed;
				
				// adjust speeds so they will all complete at the same time
				for (ent = self; ent != null; ent = ent.teamchain)
				{
					newspeed = System.Math.Abs(ent.moveinfo.distance) / time;
					ratio = newspeed / ent.moveinfo.speed;
					if (ent.moveinfo.accel == ent.moveinfo.speed)
						ent.moveinfo.accel = newspeed;
					else
						ent.moveinfo.accel *= ratio;
					if (ent.moveinfo.decel == ent.moveinfo.speed)
						ent.moveinfo.decel = newspeed;
					else
						ent.moveinfo.decel *= ratio;
					ent.moveinfo.speed = newspeed;
				}
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter20:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "think_spawn_door_trigger";
				}
				
			}
			public override bool think(edict_t ent)
			{
				edict_t other;
				float[] mins = new float[]{0, 0, 0}, maxs = new float[]{0, 0, 0};
				
				if ((ent.flags & Defines.FL_TEAMSLAVE) != 0)
					return true; // only the team leader spawns a trigger
				
				Math3D.VectorCopy(ent.absmin, mins);
				Math3D.VectorCopy(ent.absmax, maxs);
				
				for (other = ent.teamchain; other != null; other = other.teamchain)
				{
					GameBase.AddPointToBounds(other.absmin, mins, maxs);
					GameBase.AddPointToBounds(other.absmax, mins, maxs);
				}
				
				// expand
				mins[0] -= 60;
				mins[1] -= 60;
				maxs[0] += 60;
				maxs[1] += 60;
				
				other = GameUtil.G_Spawn();
				Math3D.VectorCopy(mins, other.mins);
				Math3D.VectorCopy(maxs, other.maxs);
				other.owner = ent;
				other.solid = Defines.SOLID_TRIGGER;
				other.movetype = Defines.MOVETYPE_NONE;
				other.touch = Suake2.UI.game.GameFunc.Touch_DoorTrigger;
				GameBase.gi.linkentity(other);
				
				if ((ent.spawnflags & jake2.game.GameFunc.DOOR_START_OPEN) != 0)
					jake2.game.GameFunc.door_use_areaportals(ent, true);
				
				jake2.game.GameFunc.Think_CalcMoveSpeed.think(ent);
				return true;
			}
		}
		public class AnonymousClassEntBlockedAdapter2:EntBlockedAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_blocked";
				}
				
			}
			public override void  blocked(edict_t self, edict_t other)
			{
				edict_t ent;
				
				if (0 == (other.svflags & Defines.SVF_MONSTER) && (null == other.client))
				{
					// give it a chance to go away on it's own terms (like gibs)
					GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, 100000, 1, 0, Defines.MOD_CRUSH);
					// if it's still there, nuke it
					if (other != null)
						GameMisc.BecomeExplosion1(other);
					return ;
				}
				
				GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, 1, 0, Defines.MOD_CRUSH);
				
				if ((self.spawnflags & jake2.game.GameFunc.DOOR_CRUSHER) != 0)
					return ;
				
				// if a door has a negative wait, it would never come back if
				// blocked,
				// so let it just squash the object to death real fast
				if (self.moveinfo.wait >= 0)
				{
					if (self.moveinfo.state == jake2.game.GameFunc.STATE_DOWN)
					{
						for (ent = self.teammaster; ent != null; ent = ent.teamchain)
							jake2.game.GameFunc.door_go_up(ent, ent.activator);
					}
					else
					{
						for (ent = self.teammaster; ent != null; ent = ent.teamchain)
							jake2.game.GameFunc.door_go_down.think(ent);
					}
				}
			}
		}
		public class AnonymousClassEntDieAdapter1:EntDieAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_killed";
				}
				
			}
			public override void  die(edict_t self, edict_t inflictor, edict_t attacker, int damage, float[] point)
			{
				edict_t ent;
				
				for (ent = self.teammaster; ent != null; ent = ent.teamchain)
				{
					ent.health = ent.max_health;
					ent.takedamage = Defines.DAMAGE_NO;
				}
				jake2.game.GameFunc.door_use.use(self.teammaster, attacker, attacker);
			}
		}
		public class AnonymousClassEntTouchAdapter4:EntTouchAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_touch";
				}
				
			}
			public override void  touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf)
			{
				if (null == other.client)
					return ;
				
				if (GameBase.level.time < self.touch_debounce_time)
					return ;
				self.touch_debounce_time = GameBase.level.time + 5.0f;
				
				GameBase.gi.centerprintf(other, self.message);
				GameBase.gi.sound(other, Defines.CHAN_AUTO, GameBase.gi.soundindex("misc/talk1.wav"), 1, Defines.ATTN_NORM, 0);
			}
		}
		public class AnonymousClassEntThinkAdapter21:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "sp_func_door";
				}
				
			}
			public override bool think(edict_t ent)
			{
				float[] abs_movedir = new float[]{0, 0, 0};
				
				if (ent.sounds != 1)
				{
					ent.moveinfo.sound_start = GameBase.gi.soundindex("doors/dr1_strt.wav");
					ent.moveinfo.sound_middle = GameBase.gi.soundindex("doors/dr1_mid.wav");
					ent.moveinfo.sound_end = GameBase.gi.soundindex("doors/dr1_end.wav");
				}
				
				GameBase.G_SetMovedir(ent.s.angles, ent.movedir);
				ent.movetype = Defines.MOVETYPE_PUSH;
				ent.solid = Defines.SOLID_BSP;
				GameBase.gi.setmodel(ent, ent.model);
				
				ent.blocked = Suake2.UI.game.GameFunc.door_blocked;
				ent.use = Suake2.UI.game.GameFunc.door_use;
				
				if (0 == ent.speed)
					ent.speed = 100;
				if (GameBase.deathmatch.value_Renamed != 0)
					ent.speed *= 2;
				
				if (0 == ent.accel)
					ent.accel = ent.speed;
				if (0 == ent.decel)
					ent.decel = ent.speed;
				
				if (0 == ent.wait)
					ent.wait = 3;
				if (0 == GameBase.st.lip)
					GameBase.st.lip = 8;
				if (0 == ent.dmg)
					ent.dmg = 2;
				
				// calculate second position
				Math3D.VectorCopy(ent.s.origin, ent.pos1);
				abs_movedir[0] = System.Math.Abs(ent.movedir[0]);
				abs_movedir[1] = System.Math.Abs(ent.movedir[1]);
				abs_movedir[2] = System.Math.Abs(ent.movedir[2]);
				ent.moveinfo.distance = abs_movedir[0] * ent.size[0] + abs_movedir[1] * ent.size[1] + abs_movedir[2] * ent.size[2] - GameBase.st.lip;
				
				Math3D.VectorMA(ent.pos1, ent.moveinfo.distance, ent.movedir, ent.pos2);
				
				// if it starts open, switch the positions
				if ((ent.spawnflags & jake2.game.GameFunc.DOOR_START_OPEN) != 0)
				{
					Math3D.VectorCopy(ent.pos2, ent.s.origin);
					Math3D.VectorCopy(ent.pos1, ent.pos2);
					Math3D.VectorCopy(ent.s.origin, ent.pos1);
				}
				
				ent.moveinfo.state = Suake2.UI.game.GameFunc.STATE_BOTTOM;
				
				if (ent.health != 0)
				{
					ent.takedamage = Defines.DAMAGE_YES;
					ent.die = Suake2.UI.game.GameFunc.door_killed;
					ent.max_health = ent.health;
				}
				else if (ent.targetname != null && ent.message != null)
				{
					GameBase.gi.soundindex("misc/talk.wav");
					ent.touch = Suake2.UI.game.GameFunc.door_touch;
				}
				
				ent.moveinfo.speed = ent.speed;
				ent.moveinfo.accel = ent.accel;
				ent.moveinfo.decel = ent.decel;
				ent.moveinfo.wait = ent.wait;
				Math3D.VectorCopy(ent.pos1, ent.moveinfo.start_origin);
				Math3D.VectorCopy(ent.s.angles, ent.moveinfo.start_angles);
				Math3D.VectorCopy(ent.pos2, ent.moveinfo.end_origin);
				Math3D.VectorCopy(ent.s.angles, ent.moveinfo.end_angles);
				
				if ((ent.spawnflags & 16) != 0)
					ent.s.effects |= Defines.EF_ANIM_ALL;
				if ((ent.spawnflags & 64) != 0)
					ent.s.effects |= Defines.EF_ANIM_ALLFAST;
				
				// to simplify logic elsewhere, make non-teamed doors into a team of
				// one
				if (null == ent.team)
					ent.teammaster = ent;
				
				GameBase.gi.linkentity(ent);
				
				ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
				if (ent.health != 0 || ent.targetname != null)
					ent.think = Suake2.UI.game.GameFunc.Think_CalcMoveSpeed;
				else
					ent.think = Suake2.UI.game.GameFunc.Think_SpawnDoorTrigger;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter22:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "sp_func_door_rotating";
				}
				
			}
			public override bool think(edict_t ent)
			{
				Math3D.VectorClear(ent.s.angles);
				
				// set the axis of rotation
				Math3D.VectorClear(ent.movedir);
				if ((ent.spawnflags & jake2.game.GameFunc.DOOR_X_AXIS) != 0)
					ent.movedir[2] = 1.0f;
				else if ((ent.spawnflags & jake2.game.GameFunc.DOOR_Y_AXIS) != 0)
					ent.movedir[0] = 1.0f;
				// Z_AXIS
				else
					ent.movedir[1] = 1.0f;
				
				// check for reverse rotation
				if ((ent.spawnflags & jake2.game.GameFunc.DOOR_REVERSE) != 0)
					Math3D.VectorNegate(ent.movedir, ent.movedir);
				
				if (0 == GameBase.st.distance)
				{
					GameBase.gi.dprintf(ent.classname + " at " + Lib.vtos(ent.s.origin) + " with no distance set\n");
					GameBase.st.distance = 90;
				}
				
				Math3D.VectorCopy(ent.s.angles, ent.pos1);
				Math3D.VectorMA(ent.s.angles, GameBase.st.distance, ent.movedir, ent.pos2);
				ent.moveinfo.distance = GameBase.st.distance;
				
				ent.movetype = Defines.MOVETYPE_PUSH;
				ent.solid = Defines.SOLID_BSP;
				GameBase.gi.setmodel(ent, ent.model);
				
				ent.blocked = Suake2.UI.game.GameFunc.door_blocked;
				ent.use = Suake2.UI.game.GameFunc.door_use;
				
				if (0 == ent.speed)
					ent.speed = 100;
				if (0 == ent.accel)
					ent.accel = ent.speed;
				if (0 == ent.decel)
					ent.decel = ent.speed;
				
				if (0 == ent.wait)
					ent.wait = 3;
				if (0 == ent.dmg)
					ent.dmg = 2;
				
				if (ent.sounds != 1)
				{
					ent.moveinfo.sound_start = GameBase.gi.soundindex("doors/dr1_strt.wav");
					ent.moveinfo.sound_middle = GameBase.gi.soundindex("doors/dr1_mid.wav");
					ent.moveinfo.sound_end = GameBase.gi.soundindex("doors/dr1_end.wav");
				}
				
				// if it starts open, switch the positions
				if ((ent.spawnflags & jake2.game.GameFunc.DOOR_START_OPEN) != 0)
				{
					Math3D.VectorCopy(ent.pos2, ent.s.angles);
					Math3D.VectorCopy(ent.pos1, ent.pos2);
					Math3D.VectorCopy(ent.s.angles, ent.pos1);
					Math3D.VectorNegate(ent.movedir, ent.movedir);
				}
				
				if (ent.health != 0)
				{
					ent.takedamage = Defines.DAMAGE_YES;
					ent.die = Suake2.UI.game.GameFunc.door_killed;
					ent.max_health = ent.health;
				}
				
				if (ent.targetname != null && ent.message != null)
				{
					GameBase.gi.soundindex("misc/talk.wav");
					ent.touch = Suake2.UI.game.GameFunc.door_touch;
				}
				
				ent.moveinfo.state = Suake2.UI.game.GameFunc.STATE_BOTTOM;
				ent.moveinfo.speed = ent.speed;
				ent.moveinfo.accel = ent.accel;
				ent.moveinfo.decel = ent.decel;
				ent.moveinfo.wait = ent.wait;
				Math3D.VectorCopy(ent.s.origin, ent.moveinfo.start_origin);
				Math3D.VectorCopy(ent.pos1, ent.moveinfo.start_angles);
				Math3D.VectorCopy(ent.s.origin, ent.moveinfo.end_origin);
				Math3D.VectorCopy(ent.pos2, ent.moveinfo.end_angles);
				
				if ((ent.spawnflags & 16) != 0)
					ent.s.effects |= Defines.EF_ANIM_ALL;
				
				// to simplify logic elsewhere, make non-teamed doors into a team of
				// one
				if (ent.team == null)
					ent.teammaster = ent;
				
				GameBase.gi.linkentity(ent);
				
				ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
				if (ent.health != 0 || ent.targetname != null)
					ent.think = Suake2.UI.game.GameFunc.Think_CalcMoveSpeed;
				else
					ent.think = Suake2.UI.game.GameFunc.Think_SpawnDoorTrigger;
				return true;
			}
		}
		public class AnonymousClassEntBlockedAdapter3:EntBlockedAdapter
		{
			override public System.String ID
			{
				get
				{
					return "train_blocked";
				}
				
			}
			public override void  blocked(edict_t self, edict_t other)
			{
				if (0 == (other.svflags & Defines.SVF_MONSTER) && (null == other.client))
				{
					// give it a chance to go away on it's own terms (like gibs)
					GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, 100000, 1, 0, Defines.MOD_CRUSH);
					// if it's still there, nuke it
					if (other != null)
						GameMisc.BecomeExplosion1(other);
					return ;
				}
				
				if (GameBase.level.time < self.touch_debounce_time)
					return ;
				
				if (self.dmg == 0)
					return ;
				self.touch_debounce_time = GameBase.level.time + 0.5f;
				GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, 1, 0, Defines.MOD_CRUSH);
			}
		}
		public class AnonymousClassEntThinkAdapter23:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "train_wait";
				}
				
			}
			public override bool think(edict_t self)
			{
				if (self.target_ent.pathtarget != null)
				{
					System.String savetarget;
					edict_t ent;
					
					ent = self.target_ent;
					savetarget = ent.target;
					ent.target = ent.pathtarget;
					GameUtil.G_UseTargets(ent, self.activator);
					ent.target = savetarget;
					
					// make sure we didn't get killed by a killtarget
					if (!self.inuse)
						return true;
				}
				
				if (self.moveinfo.wait != 0)
				{
					if (self.moveinfo.wait > 0)
					{
						self.nextthink = GameBase.level.time + self.moveinfo.wait;
						self.think = Suake2.UI.game.GameFunc.train_next;
					}
					else if (0 != (self.spawnflags & jake2.game.GameFunc.TRAIN_TOGGLE))
					// && wait < 0
					{
						jake2.game.GameFunc.train_next.think(self);
						self.spawnflags &= ~ jake2.game.GameFunc.TRAIN_START_ON;
						Math3D.VectorClear(self.velocity);
						self.nextthink = 0;
					}
					
					if (0 == (self.flags & Defines.FL_TEAMSLAVE))
					{
						if (self.moveinfo.sound_end != 0)
							GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_end, 1, Defines.ATTN_STATIC, 0);
						self.s.sound = 0;
					}
				}
				else
				{
					jake2.game.GameFunc.train_next.think(self);
				}
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter24:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "train_next";
				}
				
			}
			public override bool think(edict_t self)
			{
				edict_t ent = null;
				float[] dest = new float[]{0, 0, 0};
				bool first;
				
				first = true;
				
				bool dogoto = true;
				while (dogoto)
				{
					if (null == self.target)
					{
						//			gi.dprintf ("train_next: no next target\n");
						return true;
					}
					
					ent = GameBase.G_PickTarget(self.target);
					if (null == ent)
					{
						GameBase.gi.dprintf("train_next: bad target " + self.target + "\n");
						return true;
					}
					
					self.target = ent.target;
					dogoto = false;
					// check for a teleport path_corner
					if ((ent.spawnflags & 1) != 0)
					{
						if (!first)
						{
							GameBase.gi.dprintf("connected teleport path_corners, see " + ent.classname + " at " + Lib.vtos(ent.s.origin) + "\n");
							return true;
						}
						first = false;
						Math3D.VectorSubtract(ent.s.origin, self.mins, self.s.origin);
						Math3D.VectorCopy(self.s.origin, self.s.old_origin);
						self.s.event_Renamed = Defines.EV_OTHER_TELEPORT;
						GameBase.gi.linkentity(self);
						dogoto = true;
					}
				}
				self.moveinfo.wait = ent.wait;
				self.target_ent = ent;
				
				if (0 == (self.flags & Defines.FL_TEAMSLAVE))
				{
					if (self.moveinfo.sound_start != 0)
						GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_start, 1, Defines.ATTN_STATIC, 0);
					self.s.sound = self.moveinfo.sound_middle;
				}
				
				Math3D.VectorSubtract(ent.s.origin, self.mins, dest);
				self.moveinfo.state = Suake2.UI.game.GameFunc.STATE_TOP;
				Math3D.VectorCopy(self.s.origin, self.moveinfo.start_origin);
				Math3D.VectorCopy(dest, self.moveinfo.end_origin);
				jake2.game.GameFunc.Move_Calc(self, dest, jake2.game.GameFunc.train_wait);
				self.spawnflags |= jake2.game.GameFunc.TRAIN_START_ON;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter25:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "func_train_find";
				}
				
			}
			public override bool think(edict_t self)
			{
				edict_t ent;
				
				if (null == self.target)
				{
					GameBase.gi.dprintf("train_find: no target\n");
					return true;
				}
				ent = GameBase.G_PickTarget(self.target);
				if (null == ent)
				{
					GameBase.gi.dprintf("train_find: target " + self.target + " not found\n");
					return true;
				}
				self.target = ent.target;
				
				Math3D.VectorSubtract(ent.s.origin, self.mins, self.s.origin);
				GameBase.gi.linkentity(self);
				
				// if not triggered, start immediately
				if (null == self.targetname)
					self.spawnflags |= jake2.game.GameFunc.TRAIN_START_ON;
				
				if ((self.spawnflags & jake2.game.GameFunc.TRAIN_START_ON) != 0)
				{
					self.nextthink = GameBase.level.time + Defines.FRAMETIME;
					self.think = Suake2.UI.game.GameFunc.train_next;
					self.activator = self;
				}
				return true;
			}
		}
		public class AnonymousClassEntUseAdapter4:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "train_use";
				}
				
			}
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				self.activator = activator;
				
				if ((self.spawnflags & jake2.game.GameFunc.TRAIN_START_ON) != 0)
				{
					if (0 == (self.spawnflags & jake2.game.GameFunc.TRAIN_TOGGLE))
						return ;
					self.spawnflags &= ~ jake2.game.GameFunc.TRAIN_START_ON;
					Math3D.VectorClear(self.velocity);
					self.nextthink = 0;
				}
				else
				{
					if (self.target_ent != null)
						jake2.game.GameFunc.train_resume(self);
					else
						jake2.game.GameFunc.train_next.think(self);
				}
			}
		}
		public class AnonymousClassEntUseAdapter5:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "trigger_elevator_use";
				}
				
			}
			
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				edict_t target;
				
				if (0 != self.movetarget.nextthink)
				{
					//			gi.dprintf("elevator busy\n");
					return ;
				}
				
				if (null == other.pathtarget)
				{
					GameBase.gi.dprintf("elevator used with no pathtarget\n");
					return ;
				}
				
				target = GameBase.G_PickTarget(other.pathtarget);
				if (null == target)
				{
					GameBase.gi.dprintf("elevator used with bad pathtarget: " + other.pathtarget + "\n");
					return ;
				}
				
				self.movetarget.target_ent = target;
				jake2.game.GameFunc.train_resume(self.movetarget);
			}
		}
		public class AnonymousClassEntThinkAdapter26:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "trigger_elevator_init";
				}
				
			}
			public override bool think(edict_t self)
			{
				if (null == self.target)
				{
					GameBase.gi.dprintf("trigger_elevator has no target\n");
					return true;
				}
				self.movetarget = GameBase.G_PickTarget(self.target);
				if (null == self.movetarget)
				{
					GameBase.gi.dprintf("trigger_elevator unable to find target " + self.target + "\n");
					return true;
				}
				if (Lib.strcmp(self.movetarget.classname, "func_train") != 0)
				{
					GameBase.gi.dprintf("trigger_elevator target " + self.target + " is not a train\n");
					return true;
				}
				
				self.use = Suake2.UI.game.GameFunc.trigger_elevator_use;
				self.svflags = Defines.SVF_NOCLIENT;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter27:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "sp_trigger_elevator";
				}
				
			}
			public override bool think(edict_t self)
			{
				self.think = Suake2.UI.game.GameFunc.trigger_elevator_init;
				self.nextthink = GameBase.level.time + Defines.FRAMETIME;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter28:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "func_timer_think";
				}
				
			}
			public override bool think(edict_t self)
			{
				GameUtil.G_UseTargets(self, self.activator);
				self.nextthink = GameBase.level.time + self.wait + Lib.crandom() * self.random;
				return true;
			}
		}
		public class AnonymousClassEntUseAdapter6:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "func_timer_use";
				}
				
			}
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				self.activator = activator;
				
				// if on, turn it off
				if (self.nextthink != 0)
				{
					self.nextthink = 0;
					return ;
				}
				
				// turn it on
				if (self.delay != 0)
					self.nextthink = GameBase.level.time + self.delay;
				else
					jake2.game.GameFunc.func_timer_think.think(self);
			}
		}
		public class AnonymousClassEntUseAdapter7:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "func_conveyor_use";
				}
				
			}
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				if ((self.spawnflags & 1) != 0)
				{
					self.speed = 0;
					self.spawnflags &= ~ 1;
				}
				else
				{
					self.speed = self.count;
					self.spawnflags |= 1;
				}
				
				if (0 == (self.spawnflags & 2))
					self.count = 0;
			}
		}
		public class AnonymousClassEntThinkAdapter29:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "sp_func_conveyor";
				}
				
			}
			public override bool think(edict_t self)
			{
				
				if (0 == self.speed)
					self.speed = 100;
				
				if (0 == (self.spawnflags & 1))
				{
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					self.count = (int) self.speed;
					self.speed = 0;
				}
				
				self.use = Suake2.UI.game.GameFunc.func_conveyor_use;
				
				GameBase.gi.setmodel(self, self.model);
				self.solid = Defines.SOLID_BSP;
				GameBase.gi.linkentity(self);
				return true;
			}
		}
		public class AnonymousClassEntUseAdapter8:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_use";
				}
				
			}
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				// make sure we're not already moving
				if (!Math3D.VectorEquals(self.s.origin, Globals.vec3_origin))
					return ;
				
				jake2.game.GameFunc.Move_Calc(self, self.pos1, jake2.game.GameFunc.door_secret_move1);
				jake2.game.GameFunc.door_use_areaportals(self, true);
			}
		}
		public class AnonymousClassEntThinkAdapter30:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_move1";
				}
				
			}
			public override bool think(edict_t self)
			{
				self.nextthink = GameBase.level.time + 1.0f;
				self.think = Suake2.UI.game.GameFunc.door_secret_move2;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter31:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_move2";
				}
				
			}
			public override bool think(edict_t self)
			{
				jake2.game.GameFunc.Move_Calc(self, self.pos2, jake2.game.GameFunc.door_secret_move3);
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter32:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_move3";
				}
				
			}
			public override bool think(edict_t self)
			{
				if (self.wait == - 1)
					return true;
				self.nextthink = GameBase.level.time + self.wait;
				self.think = Suake2.UI.game.GameFunc.door_secret_move4;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter33:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_move4";
				}
				
			}
			public override bool think(edict_t self)
			{
				jake2.game.GameFunc.Move_Calc(self, self.pos1, jake2.game.GameFunc.door_secret_move5);
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter34:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_move5";
				}
				
			}
			public override bool think(edict_t self)
			{
				self.nextthink = GameBase.level.time + 1.0f;
				self.think = Suake2.UI.game.GameFunc.door_secret_move6;
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter35:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_move6";
				}
				
			}
			public override bool think(edict_t self)
			{
				jake2.game.GameFunc.Move_Calc(self, Globals.vec3_origin, jake2.game.GameFunc.door_secret_done);
				return true;
			}
		}
		public class AnonymousClassEntThinkAdapter36:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_move7";
				}
				
			}
			public override bool think(edict_t self)
			{
				if (null == (self.targetname) || 0 != (self.spawnflags & jake2.game.GameFunc.SECRET_ALWAYS_SHOOT))
				{
					self.health = 0;
					self.takedamage = Defines.DAMAGE_YES;
				}
				jake2.game.GameFunc.door_use_areaportals(self, false);
				return true;
			}
		}
		public class AnonymousClassEntBlockedAdapter4:EntBlockedAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_blocked";
				}
				
			}
			public override void  blocked(edict_t self, edict_t other)
			{
				if (0 == (other.svflags & Defines.SVF_MONSTER) && (null == other.client))
				{
					// give it a chance to go away on it's own terms (like gibs)
					GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, 100000, 1, 0, Defines.MOD_CRUSH);
					// if it's still there, nuke it
					if (other != null)
						GameMisc.BecomeExplosion1(other);
					return ;
				}
				
				if (GameBase.level.time < self.touch_debounce_time)
					return ;
				self.touch_debounce_time = GameBase.level.time + 0.5f;
				
				GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, 1, 0, Defines.MOD_CRUSH);
			}
		}
		public class AnonymousClassEntDieAdapter2:EntDieAdapter
		{
			override public System.String ID
			{
				get
				{
					return "door_secret_die";
				}
				
			}
			public override void  die(edict_t self, edict_t inflictor, edict_t attacker, int damage, float[] point)
			{
				self.takedamage = Defines.DAMAGE_NO;
				jake2.game.GameFunc.door_secret_use.use(self, attacker, attacker);
			}
		}
		public class AnonymousClassEntThinkAdapter37:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "sp_func_door_secret";
				}
				
			}
			public override bool think(edict_t ent)
			{
				float[] forward = new float[]{0, 0, 0}, right = new float[]{0, 0, 0}, up = new float[]{0, 0, 0};
				float side;
				float width;
				float length;
				
				ent.moveinfo.sound_start = GameBase.gi.soundindex("doors/dr1_strt.wav");
				ent.moveinfo.sound_middle = GameBase.gi.soundindex("doors/dr1_mid.wav");
				ent.moveinfo.sound_end = GameBase.gi.soundindex("doors/dr1_end.wav");
				
				ent.movetype = Defines.MOVETYPE_PUSH;
				ent.solid = Defines.SOLID_BSP;
				GameBase.gi.setmodel(ent, ent.model);
				
				ent.blocked = Suake2.UI.game.GameFunc.door_secret_blocked;
				ent.use = Suake2.UI.game.GameFunc.door_secret_use;
				
				if (null == (ent.targetname) || 0 != (ent.spawnflags & jake2.game.GameFunc.SECRET_ALWAYS_SHOOT))
				{
					ent.health = 0;
					ent.takedamage = Defines.DAMAGE_YES;
					ent.die = Suake2.UI.game.GameFunc.door_secret_die;
				}
				
				if (0 == ent.dmg)
					ent.dmg = 2;
				
				if (0 == ent.wait)
					ent.wait = 5;
				
				ent.moveinfo.accel = ent.moveinfo.decel = ent.moveinfo.speed = 50;
				
				// calculate positions
				Math3D.AngleVectors(ent.s.angles, forward, right, up);
				Math3D.VectorClear(ent.s.angles);
				side = 1.0f - (ent.spawnflags & jake2.game.GameFunc.SECRET_1ST_LEFT);
				if ((ent.spawnflags & jake2.game.GameFunc.SECRET_1ST_DOWN) != 0)
					width = System.Math.Abs(Math3D.DotProduct(up, ent.size));
				else
					width = System.Math.Abs(Math3D.DotProduct(right, ent.size));
				length = System.Math.Abs(Math3D.DotProduct(forward, ent.size));
				if ((ent.spawnflags & jake2.game.GameFunc.SECRET_1ST_DOWN) != 0)
					Math3D.VectorMA(ent.s.origin, (- 1) * width, up, ent.pos1);
				else
					Math3D.VectorMA(ent.s.origin, side * width, right, ent.pos1);
				Math3D.VectorMA(ent.pos1, length, forward, ent.pos2);
				
				if (ent.health != 0)
				{
					ent.takedamage = Defines.DAMAGE_YES;
					ent.die = Suake2.UI.game.GameFunc.door_killed;
					ent.max_health = ent.health;
				}
				else if (ent.targetname != null && ent.message != null)
				{
					GameBase.gi.soundindex("misc/talk.wav");
					ent.touch = Suake2.UI.game.GameFunc.door_touch;
				}
				
				ent.classname = "func_door";
				
				GameBase.gi.linkentity(ent);
				return true;
			}
		}
		public class AnonymousClassEntUseAdapter9:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_killbox";
				}
				
			}
			public override void  use(edict_t self, edict_t other, edict_t activator)
			{
				GameUtil.KillBox(self);
			}
		}
		public class AnonymousClassEntThinkAdapter38:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "sp_func_killbox";
				}
				
			}
			public override bool think(edict_t ent)
			{
				GameBase.gi.setmodel(ent, ent.model);
				ent.use = Suake2.UI.game.GameFunc.use_killbox;
				ent.svflags = Defines.SVF_NOCLIENT;
				return true;
			}
		}
		
		internal static void  Move_Calc(edict_t ent, float[] dest, EntThinkAdapter func)
		{
			Math3D.VectorClear(ent.velocity);
			Math3D.VectorSubtract(dest, ent.s.origin, ent.moveinfo.dir);
			ent.moveinfo.remaining_distance = Math3D.VectorNormalize(ent.moveinfo.dir);
			
			ent.moveinfo.endfunc = func;
			
			if (ent.moveinfo.speed == ent.moveinfo.accel && ent.moveinfo.speed == ent.moveinfo.decel)
			{
				if (GameBase.level.current_entity == ((ent.flags & Defines.FL_TEAMSLAVE) != 0?ent.teammaster:ent))
				{
					Move_Begin.think(ent);
				}
				else
				{
					ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
					ent.think = Move_Begin;
				}
			}
			else
			{
				// accelerative
				ent.moveinfo.current_speed = 0;
				ent.think = Think_AccelMove;
				ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
			}
		}
		
		internal static void  AngleMove_Calc(edict_t ent, EntThinkAdapter func)
		{
			Math3D.VectorClear(ent.avelocity);
			ent.moveinfo.endfunc = func;
			if (GameBase.level.current_entity == ((ent.flags & Defines.FL_TEAMSLAVE) != 0?ent.teammaster:ent))
			{
				AngleMove_Begin.think(ent);
			}
			else
			{
				ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
				ent.think = AngleMove_Begin;
			}
		}
		
		/// <summary> Think_AccelMove
		/// 
		/// The team has completed a frame of movement, so change the speed for the
		/// next frame.
		/// </summary>
		internal static float AccelerationDistance(float target, float rate)
		{
			return target * ((target / rate) + 1) / 2;
		}
		
		
		internal static void  plat_CalcAcceleratedMove(moveinfo_t moveinfo)
		{
			float accel_dist;
			float decel_dist;
			
			moveinfo.move_speed = moveinfo.speed;
			
			if (moveinfo.remaining_distance < moveinfo.accel)
			{
				moveinfo.current_speed = moveinfo.remaining_distance;
				return ;
			}
			
			accel_dist = AccelerationDistance(moveinfo.speed, moveinfo.accel);
			decel_dist = AccelerationDistance(moveinfo.speed, moveinfo.decel);
			
			if ((moveinfo.remaining_distance - accel_dist - decel_dist) < 0)
			{
				float f;
				
				f = (moveinfo.accel + moveinfo.decel) / (moveinfo.accel * moveinfo.decel);
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				moveinfo.move_speed = (float) ((- 2 + System.Math.Sqrt(4 - 4 * f * ((- 2) * moveinfo.remaining_distance))) / (2 * f));
				decel_dist = AccelerationDistance(moveinfo.move_speed, moveinfo.decel);
			}
			
			moveinfo.decel_distance = decel_dist;
		}
		
		
		internal static void  plat_Accelerate(moveinfo_t moveinfo)
		{
			// are we decelerating?
			if (moveinfo.remaining_distance <= moveinfo.decel_distance)
			{
				if (moveinfo.remaining_distance < moveinfo.decel_distance)
				{
					if (moveinfo.next_speed != 0)
					{
						moveinfo.current_speed = moveinfo.next_speed;
						moveinfo.next_speed = 0;
						return ;
					}
					if (moveinfo.current_speed > moveinfo.decel)
						moveinfo.current_speed -= moveinfo.decel;
				}
				return ;
			}
			
			// are we at full speed and need to start decelerating during this move?
			if (moveinfo.current_speed == moveinfo.move_speed)
				if ((moveinfo.remaining_distance - moveinfo.current_speed) < moveinfo.decel_distance)
				{
					float p1_distance;
					float p2_distance;
					float distance;
					
					p1_distance = moveinfo.remaining_distance - moveinfo.decel_distance;
					p2_distance = moveinfo.move_speed * (1.0f - (p1_distance / moveinfo.move_speed));
					distance = p1_distance + p2_distance;
					moveinfo.current_speed = moveinfo.move_speed;
					moveinfo.next_speed = moveinfo.move_speed - moveinfo.decel * (p2_distance / distance);
					return ;
				}
			
			// are we accelerating?
			if (moveinfo.current_speed < moveinfo.speed)
			{
				float old_speed;
				float p1_distance;
				float p1_speed;
				float p2_distance;
				float distance;
				
				old_speed = moveinfo.current_speed;
				
				// figure simple acceleration up to move_speed
				moveinfo.current_speed += moveinfo.accel;
				if (moveinfo.current_speed > moveinfo.speed)
					moveinfo.current_speed = moveinfo.speed;
				
				// are we accelerating throughout this entire move?
				if ((moveinfo.remaining_distance - moveinfo.current_speed) >= moveinfo.decel_distance)
					return ;
				
				// during this move we will accelrate from current_speed to
				// move_speed
				// and cross over the decel_distance; figure the average speed for
				// the
				// entire move
				p1_distance = moveinfo.remaining_distance - moveinfo.decel_distance;
				p1_speed = (old_speed + moveinfo.move_speed) / 2.0f;
				p2_distance = moveinfo.move_speed * (1.0f - (p1_distance / p1_speed));
				distance = p1_distance + p2_distance;
				moveinfo.current_speed = (p1_speed * (p1_distance / distance)) + (moveinfo.move_speed * (p2_distance / distance));
				moveinfo.next_speed = moveinfo.move_speed - moveinfo.decel * (p2_distance / distance);
				return ;
			}
			
			// we are at constant velocity (move_speed)
			return ;
		}
		
		
		internal static void  plat_go_up(edict_t ent)
		{
			if (0 == (ent.flags & Defines.FL_TEAMSLAVE))
			{
				if (ent.moveinfo.sound_start != 0)
					GameBase.gi.sound(ent, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, ent.moveinfo.sound_start, 1, Defines.ATTN_STATIC, 0);
				ent.s.sound = ent.moveinfo.sound_middle;
			}
			ent.moveinfo.state = STATE_UP;
			Move_Calc(ent, ent.moveinfo.start_origin, plat_hit_top);
		}
		
		internal static void  plat_spawn_inside_trigger(edict_t ent)
		{
			edict_t trigger;
			float[] tmin = new float[]{0, 0, 0}, tmax = new float[]{0, 0, 0};
			
			//
			//	   middle trigger
			//	
			trigger = GameUtil.G_Spawn();
			trigger.touch = Touch_Plat_Center;
			trigger.movetype = Defines.MOVETYPE_NONE;
			trigger.solid = Defines.SOLID_TRIGGER;
			trigger.enemy = ent;
			
			tmin[0] = ent.mins[0] + 25;
			tmin[1] = ent.mins[1] + 25;
			tmin[2] = ent.mins[2];
			
			tmax[0] = ent.maxs[0] - 25;
			tmax[1] = ent.maxs[1] - 25;
			tmax[2] = ent.maxs[2] + 8;
			
			tmin[2] = tmax[2] - (ent.pos1[2] - ent.pos2[2] + GameBase.st.lip);
			
			if ((ent.spawnflags & PLAT_LOW_TRIGGER) != 0)
				tmax[2] = tmin[2] + 8;
			
			if (tmax[0] - tmin[0] <= 0)
			{
				tmin[0] = (ent.mins[0] + ent.maxs[0]) * 0.5f;
				tmax[0] = tmin[0] + 1;
			}
			if (tmax[1] - tmin[1] <= 0)
			{
				tmin[1] = (ent.mins[1] + ent.maxs[1]) * 0.5f;
				tmax[1] = tmin[1] + 1;
			}
			
			Math3D.VectorCopy(tmin, trigger.mins);
			Math3D.VectorCopy(tmax, trigger.maxs);
			
			GameBase.gi.linkentity(trigger);
		}
		
		/// <summary> QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER speed default 150
		/// 
		/// Plats are always drawn in the extended position, so they will light
		/// correctly.
		/// 
		/// If the plat is the target of another trigger or button, it will start out
		/// disabled in the extended position until it is trigger, when it will lower
		/// and become a normal plat.
		/// 
		/// "speed" overrides default 200. "accel" overrides default 500 "lip"
		/// overrides default 8 pixel lip
		/// 
		/// If the "height" key is set, that will determine the amount the plat
		/// moves, instead of being implicitly determoveinfoned by the model's
		/// height.
		/// 
		/// Set "sounds" to one of the following: 1) base fast 2) chain slow
		/// </summary>
		internal static void  SP_func_plat(edict_t ent)
		{
			Math3D.VectorClear(ent.s.angles);
			ent.solid = Defines.SOLID_BSP;
			ent.movetype = Defines.MOVETYPE_PUSH;
			
			GameBase.gi.setmodel(ent, ent.model);
			
			ent.blocked = plat_blocked;
			
			if (0 == ent.speed)
				ent.speed = 20;
			else
				ent.speed = (float) (ent.speed * 0.1);
			
			if (ent.accel == 0)
				ent.accel = 5;
			else
				ent.accel = (float) (ent.accel * 0.1);
			
			if (ent.decel == 0)
				ent.decel = 5;
			else
				ent.decel = (float) (ent.decel * 0.1);
			
			if (ent.dmg == 0)
				ent.dmg = 2;
			
			if (GameBase.st.lip == 0)
				GameBase.st.lip = 8;
			
			// pos1 is the top position, pos2 is the bottom
			Math3D.VectorCopy(ent.s.origin, ent.pos1);
			Math3D.VectorCopy(ent.s.origin, ent.pos2);
			if (GameBase.st.height != 0)
				ent.pos2[2] -= GameBase.st.height;
			else
				ent.pos2[2] -= ((ent.maxs[2] - ent.mins[2]) - GameBase.st.lip);
			
			ent.use = Use_Plat;
			
			plat_spawn_inside_trigger(ent); // the "start moving" trigger
			
			if (ent.targetname != null)
			{
				ent.moveinfo.state = STATE_UP;
			}
			else
			{
				Math3D.VectorCopy(ent.pos2, ent.s.origin);
				GameBase.gi.linkentity(ent);
				ent.moveinfo.state = STATE_BOTTOM;
			}
			
			ent.moveinfo.speed = ent.speed;
			ent.moveinfo.accel = ent.accel;
			ent.moveinfo.decel = ent.decel;
			ent.moveinfo.wait = ent.wait;
			Math3D.VectorCopy(ent.pos1, ent.moveinfo.start_origin);
			Math3D.VectorCopy(ent.s.angles, ent.moveinfo.start_angles);
			Math3D.VectorCopy(ent.pos2, ent.moveinfo.end_origin);
			Math3D.VectorCopy(ent.s.angles, ent.moveinfo.end_angles);
			
			ent.moveinfo.sound_start = GameBase.gi.soundindex("plats/pt1_strt.wav");
			ent.moveinfo.sound_middle = GameBase.gi.soundindex("plats/pt1_mid.wav");
			ent.moveinfo.sound_end = GameBase.gi.soundindex("plats/pt1_end.wav");
		}
		
		/// <summary> DOORS
		/// 
		/// spawn a trigger surrounding the entire team unless it is already targeted
		/// by another.
		/// 
		/// </summary>
		
		/// <summary> QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER NOMONSTER ANIMATED
		/// TOGGLE ANIMATED_FAST TOGGLE wait in both the start and end states for a
		/// trigger event. START_OPEN the door to moves to its destination when
		/// spawned, and operate in reverse. It is used to temporarily or permanently
		/// close off an area when triggered (not useful for touch or takedamage
		/// doors). NOMONSTER monsters will not trigger this door
		/// 
		/// "message" is printed when the door is touched if it is a trigger door and
		/// it hasn't been fired yet "angle" determines the opening direction
		/// "targetname" if set, no touch field will be spawned and a remote button
		/// or trigger field activates the door. "health" if set, door must be shot
		/// open "speed" movement speed (100 default) "wait" wait before returning (3
		/// default, -1 = never return) "lip" lip remaining at end of move (8
		/// default) "dmg" damage to inflict when blocked (2 default) "sounds" 1)
		/// silent 2) light 3) medium 4) heavy
		/// </summary>
		
		internal static void  door_use_areaportals(edict_t self, bool open)
		{
			edict_t t = null;
			
			if (self.target == null)
				return ;
			
			EdictIterator edit = null;
			
			while ((edit = GameBase.G_Find(edit, GameBase.findByTarget, self.target)) != null)
			{
				t = edit.o;
				if (Lib.Q_stricmp(t.classname, "func_areaportal") == 0)
				{
					GameBase.gi.SetAreaPortalState(t.style, open);
				}
			}
		}
		
		internal static void  door_go_up(edict_t self, edict_t activator)
		{
			if (self.moveinfo.state == STATE_UP)
				return ; // already going up
			
			if (self.moveinfo.state == STATE_TOP)
			{
				// reset top wait time
				if (self.moveinfo.wait >= 0)
					self.nextthink = GameBase.level.time + self.moveinfo.wait;
				return ;
			}
			
			if (0 == (self.flags & Defines.FL_TEAMSLAVE))
			{
				if (self.moveinfo.sound_start != 0)
					GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_start, 1, Defines.ATTN_STATIC, 0);
				self.s.sound = self.moveinfo.sound_middle;
			}
			self.moveinfo.state = STATE_UP;
			if (Lib.strcmp(self.classname, "func_door") == 0)
				Move_Calc(self, self.moveinfo.end_origin, door_hit_top);
			else if (Lib.strcmp(self.classname, "func_door_rotating") == 0)
				AngleMove_Calc(self, door_hit_top);
			
			GameUtil.G_UseTargets(self, activator);
			door_use_areaportals(self, true);
		}
		
		/// <summary> QUAKED func_water (0 .5 .8) ? START_OPEN func_water is a moveable water
		/// brush. It must be targeted to operate. Use a non-water texture at your
		/// own risk.
		/// 
		/// START_OPEN causes the water to move to its destination when spawned and
		/// operate in reverse.
		/// 
		/// "angle" determines the opening direction (up or down only) "speed"
		/// movement speed (25 default) "wait" wait before returning (-1 default, -1 =
		/// TOGGLE) "lip" lip remaining at end of move (0 default) "sounds" (yes,
		/// these need to be changed) 0) no sound 1) water 2) lava
		/// </summary>
		
		internal static void  SP_func_water(edict_t self)
		{
			float[] abs_movedir = new float[]{0, 0, 0};
			
			GameBase.G_SetMovedir(self.s.angles, self.movedir);
			self.movetype = Defines.MOVETYPE_PUSH;
			self.solid = Defines.SOLID_BSP;
			GameBase.gi.setmodel(self, self.model);
			
			switch (self.sounds)
			{
				
				default: 
					break;
				
				
				
				case 1:  // water
					self.moveinfo.sound_start = GameBase.gi.soundindex("world/mov_watr.wav");
					self.moveinfo.sound_end = GameBase.gi.soundindex("world/stp_watr.wav");
					break;
				
				
				case 2:  // lava
					self.moveinfo.sound_start = GameBase.gi.soundindex("world/mov_watr.wav");
					self.moveinfo.sound_end = GameBase.gi.soundindex("world/stp_watr.wav");
					break;
				}
			
			// calculate second position
			Math3D.VectorCopy(self.s.origin, self.pos1);
			abs_movedir[0] = System.Math.Abs(self.movedir[0]);
			abs_movedir[1] = System.Math.Abs(self.movedir[1]);
			abs_movedir[2] = System.Math.Abs(self.movedir[2]);
			self.moveinfo.distance = abs_movedir[0] * self.size[0] + abs_movedir[1] * self.size[1] + abs_movedir[2] * self.size[2] - GameBase.st.lip;
			Math3D.VectorMA(self.pos1, self.moveinfo.distance, self.movedir, self.pos2);
			
			// if it starts open, switch the positions
			if ((self.spawnflags & DOOR_START_OPEN) != 0)
			{
				Math3D.VectorCopy(self.pos2, self.s.origin);
				Math3D.VectorCopy(self.pos1, self.pos2);
				Math3D.VectorCopy(self.s.origin, self.pos1);
			}
			
			Math3D.VectorCopy(self.pos1, self.moveinfo.start_origin);
			Math3D.VectorCopy(self.s.angles, self.moveinfo.start_angles);
			Math3D.VectorCopy(self.pos2, self.moveinfo.end_origin);
			Math3D.VectorCopy(self.s.angles, self.moveinfo.end_angles);
			
			self.moveinfo.state = STATE_BOTTOM;
			
			if (0 == self.speed)
				self.speed = 25;
			self.moveinfo.accel = self.moveinfo.decel = self.moveinfo.speed = self.speed;
			
			if (0 == self.wait)
				self.wait = - 1;
			self.moveinfo.wait = self.wait;
			
			self.use = door_use;
			
			if (self.wait == - 1)
				self.spawnflags |= DOOR_TOGGLE;
			
			self.classname = "func_door";
			
			GameBase.gi.linkentity(self);
		}
		
		internal static void  train_resume(edict_t self)
		{
			edict_t ent;
			float[] dest = new float[]{0, 0, 0};
			
			ent = self.target_ent;
			
			Math3D.VectorSubtract(ent.s.origin, self.mins, dest);
			self.moveinfo.state = STATE_TOP;
			Math3D.VectorCopy(self.s.origin, self.moveinfo.start_origin);
			Math3D.VectorCopy(dest, self.moveinfo.end_origin);
			Move_Calc(self, dest, train_wait);
			self.spawnflags |= TRAIN_START_ON;
		}
		
		internal static void  SP_func_train(edict_t self)
		{
			self.movetype = Defines.MOVETYPE_PUSH;
			
			Math3D.VectorClear(self.s.angles);
			self.blocked = train_blocked;
			if ((self.spawnflags & TRAIN_BLOCK_STOPS) != 0)
				self.dmg = 0;
			else
			{
				if (0 == self.dmg)
					self.dmg = 100;
			}
			self.solid = Defines.SOLID_BSP;
			GameBase.gi.setmodel(self, self.model);
			
			if (GameBase.st.noise != null)
				self.moveinfo.sound_middle = GameBase.gi.soundindex(GameBase.st.noise);
			
			if (0 == self.speed)
				self.speed = 100;
			
			self.moveinfo.speed = self.speed;
			self.moveinfo.accel = self.moveinfo.decel = self.moveinfo.speed;
			
			self.use = train_use;
			
			GameBase.gi.linkentity(self);
			
			if (self.target != null)
			{
				// start trains on the second frame, to make sure their targets have
				// had
				// a chance to spawn
				self.nextthink = GameBase.level.time + Defines.FRAMETIME;
				self.think = func_train_find;
			}
			else
			{
				GameBase.gi.dprintf("func_train without a target at " + Lib.vtos(self.absmin) + "\n");
			}
		}
		
		internal static void  SP_func_timer(edict_t self)
		{
			if (0 == self.wait)
				self.wait = 1.0f;
			
			self.use = func_timer_use;
			self.think = func_timer_think;
			
			if (self.random >= self.wait)
			{
				self.random = self.wait - Defines.FRAMETIME;
				GameBase.gi.dprintf("func_timer at " + Lib.vtos(self.s.origin) + " has random >= wait\n");
			}
			
			if ((self.spawnflags & 1) != 0)
			{
				self.nextthink = GameBase.level.time + 1.0f + GameBase.st.pausetime + self.delay + self.wait + Lib.crandom() * self.random;
				self.activator = self;
			}
			
			self.svflags = Defines.SVF_NOCLIENT;
		}
		
		/// <summary> PLATS
		/// 
		/// movement options:
		/// 
		/// linear smooth start, hard stop smooth start, smooth stop
		/// 
		/// start end acceleration speed deceleration begin sound end sound target
		/// fired when reaching end wait at end
		/// 
		/// object characteristics that use move segments
		/// --------------------------------------------- movetype_push, or
		/// movetype_stop action when touched action when blocked action when used
		/// disabled? auto trigger spawning
		/// 
		/// </summary>
		
		public const int PLAT_LOW_TRIGGER = 1;
		
		public const int STATE_TOP = 0;
		
		public const int STATE_BOTTOM = 1;
		
		public const int STATE_UP = 2;
		
		public const int STATE_DOWN = 3;
		
		public const int DOOR_START_OPEN = 1;
		
		public const int DOOR_REVERSE = 2;
		
		public const int DOOR_CRUSHER = 4;
		
		public const int DOOR_NOMONSTER = 8;
		
		public const int DOOR_TOGGLE = 32;
		
		public const int DOOR_X_AXIS = 64;
		
		public const int DOOR_Y_AXIS = 128;
		
		//
		//	   Support routines for movement (changes in origin using velocity)
		//
		
		//UPGRADE_NOTE: The initialization of  'Move_Done' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter Move_Done;
		
		//UPGRADE_NOTE: The initialization of  'Move_Final' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter Move_Final;
		
		//UPGRADE_NOTE: The initialization of  'Move_Begin' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter Move_Begin;
		
		//
		//	   Support routines for angular movement (changes in angle using avelocity)
		//
		
		//UPGRADE_NOTE: The initialization of  'AngleMove_Done' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter AngleMove_Done;
		
		//UPGRADE_NOTE: The initialization of  'AngleMove_Final' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter AngleMove_Final;
		
		//UPGRADE_NOTE: The initialization of  'AngleMove_Begin' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter AngleMove_Begin;
		
		//UPGRADE_NOTE: The initialization of  'Think_AccelMove' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter Think_AccelMove;
		
		//UPGRADE_NOTE: The initialization of  'plat_hit_top' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter plat_hit_top;
		
		//UPGRADE_NOTE: The initialization of  'plat_hit_bottom' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter plat_hit_bottom;
		
		//UPGRADE_NOTE: The initialization of  'plat_go_down' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter plat_go_down;
		
		//UPGRADE_NOTE: The initialization of  'plat_blocked' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntBlockedAdapter plat_blocked;
		
		//UPGRADE_NOTE: The initialization of  'Use_Plat' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter Use_Plat;
		
		//UPGRADE_NOTE: The initialization of  'Touch_Plat_Center' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntTouchAdapter Touch_Plat_Center;
		
		/// <summary> QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS
		/// TOUCH_PAIN STOP ANIMATED ANIMATED_FAST You need to have an origin brush
		/// as part of this entity. The center of that brush will be the point around
		/// which it is rotated. It will rotate around the Z axis by default. You can
		/// check either the X_AXIS or Y_AXIS box to change that.
		/// 
		/// "speed" determines how fast it moves; default value is 100. "dmg" damage
		/// to inflict when blocked (2 default)
		/// 
		/// REVERSE will cause the it to rotate in the opposite direction. STOP mean
		/// it will stop moving instead of pushing entities
		/// </summary>
		
		//UPGRADE_NOTE: The initialization of  'rotating_blocked' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntBlockedAdapter rotating_blocked;
		
		//UPGRADE_NOTE: The initialization of  'rotating_touch' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntTouchAdapter rotating_touch;
		
		//UPGRADE_NOTE: The initialization of  'rotating_use' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter rotating_use;
		
		//UPGRADE_NOTE: The initialization of  'SP_func_rotating' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter SP_func_rotating;
		
		/*
		* ======================================================================
		* 
		* BUTTONS
		* 
		* ======================================================================
		*/
		
		/*
		* QUAKED func_button (0 .5 .8) ? When a button is touched, it moves some
		* distance in the direction of it's angle, triggers all of it's targets,
		* waits some time, then returns to it's original position where it can be
		* triggered again.
		* 
		* "angle" determines the opening direction "target" all entities with a
		* matching targetname will be used "speed" override the default 40 speed
		* "wait" override the default 1 second wait (-1 = never return) "lip"
		* override the default 4 pixel lip remaining at end of move "health" if
		* set, the button must be killed instead of touched "sounds" 1) silent 2)
		* steam metal 3) wooden clunk 4) metallic click 5) in-out
		*/
		
		//UPGRADE_NOTE: The initialization of  'button_done' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter button_done;
		
		//UPGRADE_NOTE: The initialization of  'button_return' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter button_return;
		
		//UPGRADE_NOTE: The initialization of  'button_wait' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter button_wait;
		
		//UPGRADE_NOTE: The initialization of  'button_fire' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter button_fire;
		
		//UPGRADE_NOTE: The initialization of  'button_use' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter button_use;
		
		//UPGRADE_NOTE: The initialization of  'button_touch' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntTouchAdapter button_touch;
		
		//UPGRADE_NOTE: The initialization of  'button_killed' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntDieAdapter button_killed;
		
		//UPGRADE_NOTE: The initialization of  'SP_func_button' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter SP_func_button;
		
		//UPGRADE_NOTE: The initialization of  'door_hit_top' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_hit_top;
		
		//UPGRADE_NOTE: The initialization of  'door_hit_bottom' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_hit_bottom;
		
		//UPGRADE_NOTE: The initialization of  'door_go_down' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_go_down;
		
		//UPGRADE_NOTE: The initialization of  'door_use' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter door_use;
		
		//UPGRADE_NOTE: The initialization of  'Touch_DoorTrigger' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntTouchAdapter Touch_DoorTrigger;
		
		//UPGRADE_NOTE: The initialization of  'Think_CalcMoveSpeed' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter Think_CalcMoveSpeed;
		
		//UPGRADE_NOTE: The initialization of  'Think_SpawnDoorTrigger' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter Think_SpawnDoorTrigger;
		
		//UPGRADE_NOTE: The initialization of  'door_blocked' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntBlockedAdapter door_blocked;
		
		//UPGRADE_NOTE: The initialization of  'door_killed' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntDieAdapter door_killed;
		
		//UPGRADE_NOTE: The initialization of  'door_touch' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntTouchAdapter door_touch;
		
		//UPGRADE_NOTE: The initialization of  'SP_func_door' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter SP_func_door;
		
		/*
		* QUAKED func_door_rotating (0 .5 .8) ? START_OPEN REVERSE CRUSHER
		* NOMONSTER ANIMATED TOGGLE X_AXIS Y_AXIS TOGGLE causes the door to wait in
		* both the start and end states for a trigger event.
		* 
		* START_OPEN the door to moves to its destination when spawned, and operate
		* in reverse. It is used to temporarily or permanently close off an area
		* when triggered (not useful for touch or takedamage doors). NOMONSTER
		* monsters will not trigger this door
		* 
		* You need to have an origin brush as part of this entity. The center of
		* that brush will be the point around which it is rotated. It will rotate
		* around the Z axis by default. You can check either the X_AXIS or Y_AXIS
		* box to change that.
		* 
		* "distance" is how many degrees the door will be rotated. "speed"
		* determines how fast the door moves; default value is 100.
		* 
		* REVERSE will cause the door to rotate in the opposite direction.
		* 
		* "message" is printed when the door is touched if it is a trigger door and
		* it hasn't been fired yet "angle" determines the opening direction
		* "targetname" if set, no touch field will be spawned and a remote button
		* or trigger field activates the door. "health" if set, door must be shot
		* open "speed" movement speed (100 default) "wait" wait before returning (3
		* default, -1 = never return) "dmg" damage to inflict when blocked (2
		* default) "sounds" 1) silent 2) light 3) medium 4) heavy
		*/
		
		//UPGRADE_NOTE: The initialization of  'SP_func_door_rotating' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter SP_func_door_rotating;
		
		public const int TRAIN_START_ON = 1;
		
		public const int TRAIN_TOGGLE = 2;
		
		public const int TRAIN_BLOCK_STOPS = 4;
		
		/*
		* QUAKED func_train (0 .5 .8) ? START_ON TOGGLE BLOCK_STOPS Trains are
		* moving platforms that players can ride. The targets origin specifies the
		* min point of the train at each corner. The train spawns at the first
		* target it is pointing at. If the train is the target of a button or
		* trigger, it will not begin moving until activated. speed default 100 dmg
		* default 2 noise looping sound to play when the train is in motion
		*  
		*/
		
		//UPGRADE_NOTE: The initialization of  'train_blocked' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntBlockedAdapter train_blocked;
		
		//UPGRADE_NOTE: The initialization of  'train_wait' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter train_wait;
		
		//UPGRADE_NOTE: The initialization of  'train_next' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter train_next;
		
		//UPGRADE_NOTE: The initialization of  'func_train_find' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntThinkAdapter func_train_find;
		
		//UPGRADE_NOTE: The initialization of  'train_use' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntUseAdapter train_use;
		
		/*
		* QUAKED trigger_elevator (0.3 0.1 0.6) (-8 -8 -8) (8 8 8)
		*/
		//UPGRADE_NOTE: The initialization of  'trigger_elevator_use' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter trigger_elevator_use;
		
		//UPGRADE_NOTE: The initialization of  'trigger_elevator_init' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter trigger_elevator_init;
		
		//UPGRADE_NOTE: The initialization of  'SP_trigger_elevator' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter SP_trigger_elevator;
		
		/*
		* QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON "wait" base
		* time between triggering all targets, default is 1 "random" wait variance,
		* default is 0
		* 
		* so, the basic time between firing is a random time between (wait -
		* random) and (wait + random)
		* 
		* "delay" delay before first firing when turned on, default is 0
		* 
		* "pausetime" additional delay used only the very first time and only if
		* spawned with START_ON
		* 
		* These can used but not touched.
		*/
		
		//UPGRADE_NOTE: The initialization of  'func_timer_think' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter func_timer_think;
		
		//UPGRADE_NOTE: The initialization of  'func_timer_use' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter func_timer_use;
		
		/*
		* QUAKED func_conveyor (0 .5 .8) ? START_ON TOGGLE Conveyors are stationary
		* brushes that move what's on them. The brush should be have a surface with
		* at least one current content enabled. speed default 100
		*/
		
		//UPGRADE_NOTE: The initialization of  'func_conveyor_use' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter func_conveyor_use;
		
		//UPGRADE_NOTE: The initialization of  'SP_func_conveyor' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter SP_func_conveyor;
		
		/*
		* QUAKED func_door_secret (0 .5 .8) ? always_shoot 1st_left 1st_down A
		* secret door. Slide back and then to the side.
		* 
		* open_once doors never closes 1st_left 1st move is left of arrow 1st_down
		* 1st move is down from arrow always_shoot door is shootebale even if
		* targeted
		* 
		* "angle" determines the direction "dmg" damage to inflic when blocked
		* (default 2) "wait" how long to hold in the open position (default 5, -1
		* means hold)
		*/
		
		public const int SECRET_ALWAYS_SHOOT = 1;
		
		public const int SECRET_1ST_LEFT = 2;
		
		public const int SECRET_1ST_DOWN = 4;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_use' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter door_secret_use;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_move1' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_secret_move1;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_move2' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_secret_move2;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_move3' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_secret_move3;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_move4' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_secret_move4;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_move5' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_secret_move5;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_move6' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_secret_move6;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_done' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter door_secret_done;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_blocked' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntBlockedAdapter door_secret_blocked;
		
		//UPGRADE_NOTE: The initialization of  'door_secret_die' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntDieAdapter door_secret_die;
		
		//UPGRADE_NOTE: The initialization of  'SP_func_door_secret' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter SP_func_door_secret;
		
		/// <summary> QUAKED func_killbox (1 0 0) ? Kills everything inside when fired,
		/// irrespective of protection.
		/// </summary>
		//UPGRADE_NOTE: The initialization of  'use_killbox' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntUseAdapter use_killbox;
		
		//UPGRADE_NOTE: The initialization of  'SP_func_killbox' was moved to static method 'jake2.game.GameFunc'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter SP_func_killbox;
		static GameFunc()
		{
			Move_Done = new AnonymousClassEntThinkAdapter();
			Move_Final = new AnonymousClassEntThinkAdapter1();
			Move_Begin = new AnonymousClassEntThinkAdapter2();
			AngleMove_Done = new AnonymousClassEntThinkAdapter3();
			AngleMove_Final = new AnonymousClassEntThinkAdapter4();
			AngleMove_Begin = new AnonymousClassEntThinkAdapter5();
			Think_AccelMove = new AnonymousClassEntThinkAdapter6();
			plat_hit_top = new AnonymousClassEntThinkAdapter7();
			plat_hit_bottom = new AnonymousClassEntThinkAdapter8();
			plat_go_down = new AnonymousClassEntThinkAdapter9();
			plat_blocked = new AnonymousClassEntBlockedAdapter();
			Use_Plat = new AnonymousClassEntUseAdapter();
			Touch_Plat_Center = new AnonymousClassEntTouchAdapter();
			rotating_blocked = new AnonymousClassEntBlockedAdapter1();
			rotating_touch = new AnonymousClassEntTouchAdapter1();
			rotating_use = new AnonymousClassEntUseAdapter1();
			SP_func_rotating = new AnonymousClassEntThinkAdapter10();
			button_done = new AnonymousClassEntThinkAdapter11();
			button_return = new AnonymousClassEntThinkAdapter12();
			button_wait = new AnonymousClassEntThinkAdapter13();
			button_fire = new AnonymousClassEntThinkAdapter14();
			button_use = new AnonymousClassEntUseAdapter2();
			button_touch = new AnonymousClassEntTouchAdapter2();
			button_killed = new AnonymousClassEntDieAdapter();
			SP_func_button = new AnonymousClassEntThinkAdapter15();
			door_hit_top = new AnonymousClassEntThinkAdapter16();
			door_hit_bottom = new AnonymousClassEntThinkAdapter17();
			door_go_down = new AnonymousClassEntThinkAdapter18();
			door_use = new AnonymousClassEntUseAdapter3();
			Touch_DoorTrigger = new AnonymousClassEntTouchAdapter3();
			Think_CalcMoveSpeed = new AnonymousClassEntThinkAdapter19();
			Think_SpawnDoorTrigger = new AnonymousClassEntThinkAdapter20();
			door_blocked = new AnonymousClassEntBlockedAdapter2();
			door_killed = new AnonymousClassEntDieAdapter1();
			door_touch = new AnonymousClassEntTouchAdapter4();
			SP_func_door = new AnonymousClassEntThinkAdapter21();
			SP_func_door_rotating = new AnonymousClassEntThinkAdapter22();
			train_blocked = new AnonymousClassEntBlockedAdapter3();
			train_wait = new AnonymousClassEntThinkAdapter23();
			train_next = new AnonymousClassEntThinkAdapter24();
			func_train_find = new AnonymousClassEntThinkAdapter25();
			train_use = new AnonymousClassEntUseAdapter4();
			trigger_elevator_use = new AnonymousClassEntUseAdapter5();
			trigger_elevator_init = new AnonymousClassEntThinkAdapter26();
			SP_trigger_elevator = new AnonymousClassEntThinkAdapter27();
			func_timer_think = new AnonymousClassEntThinkAdapter28();
			func_timer_use = new AnonymousClassEntUseAdapter6();
			func_conveyor_use = new AnonymousClassEntUseAdapter7();
			SP_func_conveyor = new AnonymousClassEntThinkAdapter29();
			door_secret_use = new AnonymousClassEntUseAdapter8();
			door_secret_move1 = new AnonymousClassEntThinkAdapter30();
			door_secret_move2 = new AnonymousClassEntThinkAdapter31();
			door_secret_move3 = new AnonymousClassEntThinkAdapter32();
			door_secret_move4 = new AnonymousClassEntThinkAdapter33();
			door_secret_move5 = new AnonymousClassEntThinkAdapter34();
			door_secret_move6 = new AnonymousClassEntThinkAdapter35();
			door_secret_done = new AnonymousClassEntThinkAdapter36();
			door_secret_blocked = new AnonymousClassEntBlockedAdapter4();
			door_secret_die = new AnonymousClassEntDieAdapter2();
			SP_func_door_secret = new AnonymousClassEntThinkAdapter37();
			use_killbox = new AnonymousClassEntUseAdapter9();
			SP_func_killbox = new AnonymousClassEntThinkAdapter38();
		}
	}
}